package Rangel.firebrigade.buildingdetector.targetselector.directionbased;

import adf.agent.info.AgentInfo;
import Rangel.firebrigade.cluster.Cluster;
import Rangel.firebrigade.cluster.FireCluster;
import Rangel.firebrigade.buildingdetector.targetselector.DefaultFireBrigadeTargetSelector;
import Rangel.firebrigade.buildingdetector.FireBrigadeTarget;
import Rangel.firebrigade.world.RangelFireBrigadeWorld;
import Rangel.firebrigade.buildingdetector.targetselector.ZJUBaseBuildingCostComputer;
import Rangel.common.world.sorter.ConstantComparators;
import Rangel.common.world.entity.RangelBuilding;
import rescuecore2.misc.Pair;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.worldmodel.EntityID;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class DirectionBasedTargetSelector extends DefaultFireBrigadeTargetSelector {
    public DirectionBasedTargetSelector(RangelFireBrigadeWorld world, AgentInfo agentInfo) {
        super(world, agentInfo);
        buildingCostComputer = new ZJUBaseBuildingCostComputer(world);
    }

    private ZJUBaseBuildingCostComputer buildingCostComputer;


    @Override
    public FireBrigadeTarget selectTarget(Cluster targetCluster) {
        FireBrigadeTarget fireBrigadeTarget = null;
        if (targetCluster != null) {
            SortedSet<Pair<EntityID, Double>> sortedBuildings;
            sortedBuildings = calculateValue((FireCluster) targetCluster);
            if (!sortedBuildings.isEmpty()) {
                lastTarget = target;
                target = world.getRangelBuilding(sortedBuildings.first().first());
                fireBrigadeTarget = new FireBrigadeTarget(target, targetCluster);
            }
        }

        return fireBrigadeTarget;
    }


    private SortedSet<Pair<EntityID, Double>> calculateValue(FireCluster fireCluster) {

        Set<StandardEntity> borderEntities = fireCluster.getBorderEntities();
        SortedSet<Pair<EntityID, Double>> sortedBuildings = new TreeSet<>(ConstantComparators.DISTANCE_VALUE_COMPARATOR_DOUBLE);//升序排序
        List<RangelBuilding> inDirectionBuildings;

        inDirectionBuildings = fireCluster.getBuildingsInDirection();
        buildingCostComputer.updateFor(fireCluster, lastTarget);

        if (inDirectionBuildings.isEmpty()) {//计算两种不同的情况下的sortbuildings
            calculateValueForOtherBuildings(sortedBuildings, borderEntities);
        }
        calculateValueForInDirectionBuildings(sortedBuildings, inDirectionBuildings);
        return sortedBuildings;
    }

    private void calculateValueForOtherBuildings(SortedSet<Pair<EntityID, Double>> sortedBuildings, Set<StandardEntity> otherBuildings) {
        for (StandardEntity entity : otherBuildings) {
            RangelBuilding b = world.getRangelBuilding(entity.getID());
            b.BUILDING_VALUE = buildingCostComputer.getCost(b);
            sortedBuildings.add(new Pair<>(b.getID(), b.BUILDING_VALUE));
        }
    }

    private void calculateValueForInDirectionBuildings(SortedSet<Pair<EntityID, Double>> sortedBuildings, List<RangelBuilding> highValueBuildings) {
        for (RangelBuilding b : highValueBuildings) {
            b.BUILDING_VALUE = buildingCostComputer.getCost(b);
            sortedBuildings.add(new Pair<>(b.getID(), b.BUILDING_VALUE));
        }
    }

}